@scrider/formatter 1.4.3 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -43,12 +43,15 @@ __export(index_exports, {
43
43
  Registry: () => Registry,
44
44
  SCRIDER_LINE_HEIGHT_KEY: () => SCRIDER_LINE_HEIGHT_KEY,
45
45
  SCRIDER_MARGIN_AFTER_KEY: () => SCRIDER_MARGIN_AFTER_KEY,
46
+ SCRIDER_MARGIN_BEFORE_KEY: () => SCRIDER_MARGIN_BEFORE_KEY,
46
47
  alertBlockHandler: () => alertBlockHandler,
47
48
  alignFormat: () => alignFormat,
48
49
  backgroundFormat: () => backgroundFormat,
49
50
  blockFormat: () => blockFormat,
50
51
  blockLineHeightStyleParts: () => blockLineHeightStyleParts,
51
52
  blockMarginAfterStyleParts: () => blockMarginAfterStyleParts,
53
+ blockMarginBeforeStyleParts: () => blockMarginBeforeStyleParts,
54
+ blockParagraphMarginStyleParts: () => blockParagraphMarginStyleParts,
52
55
  blockPresentationStyleParts: () => blockPresentationStyleParts,
53
56
  blockquoteFormat: () => blockquoteFormat,
54
57
  boldFormat: () => boldFormat,
@@ -102,6 +105,8 @@ __export(index_exports, {
102
105
  normalizeDelta: () => normalizeDelta,
103
106
  parseScriderLineHeightMultiplier: () => parseScriderLineHeightMultiplier,
104
107
  parseScriderMarginAfterEm: () => parseScriderMarginAfterEm,
108
+ parseScriderMarginBeforeEm: () => parseScriderMarginBeforeEm,
109
+ parseScriderMarginEm: () => parseScriderMarginEm,
105
110
  preloadRemark: () => preloadRemark,
106
111
  resolveDocumentPresentation: () => resolveDocumentPresentation,
107
112
  resolveTablePresentation: () => resolveTablePresentation,
@@ -2615,6 +2620,7 @@ function slugifyWithDedup(text, usedSlugs) {
2615
2620
  // src/conversion/html/block-presentation.ts
2616
2621
  var SCRIDER_LINE_HEIGHT_KEY = "scrider-line-height";
2617
2622
  var SCRIDER_MARGIN_AFTER_KEY = "scrider-margin-after";
2623
+ var SCRIDER_MARGIN_BEFORE_KEY = "scrider-margin-before";
2618
2624
  var LINE_HEIGHT_BLOCK_TAGS = /* @__PURE__ */ new Set(["p", "li", "blockquote"]);
2619
2625
  var PARAGRAPH_SPACING_BLOCK_TAGS = /* @__PURE__ */ new Set(["p"]);
2620
2626
  function parseScriderLineHeightMultiplier(value) {
@@ -2645,7 +2651,7 @@ function blockLineHeightStyleParts(tag, blockAttributes, resolved) {
2645
2651
  }
2646
2652
  return [];
2647
2653
  }
2648
- function parseScriderMarginAfterEm(value) {
2654
+ function parseScriderMarginEm(value) {
2649
2655
  const trimmed = value.trim();
2650
2656
  if (!trimmed) return void 0;
2651
2657
  const emMatch = trimmed.match(/^(-?\d+(?:\.\d+)?)\s*em$/i);
@@ -2658,20 +2664,59 @@ function parseScriderMarginAfterEm(value) {
2658
2664
  if (Number.isFinite(n) && n >= 0) return n;
2659
2665
  return void 0;
2660
2666
  }
2661
- function marginAfterStyleParts(em) {
2662
- return [`margin-top:0`, `margin-bottom:${em}em`];
2667
+ var parseScriderMarginAfterEm = parseScriderMarginEm;
2668
+ var parseScriderMarginBeforeEm = parseScriderMarginEm;
2669
+ function resolveParagraphMarginEm(blockAttributes, blockKey, documentEm) {
2670
+ const raw = blockAttributes?.[blockKey];
2671
+ if (typeof raw === "string") {
2672
+ const fromBlock = parseScriderMarginEm(raw);
2673
+ if (fromBlock !== void 0) return fromBlock;
2674
+ }
2675
+ return documentEm;
2663
2676
  }
2664
- function blockMarginAfterStyleParts(tag, blockAttributes, resolved) {
2677
+ function blockParagraphMarginStyleParts(tag, blockAttributes, resolved) {
2665
2678
  if (!PARAGRAPH_SPACING_BLOCK_TAGS.has(tag)) return [];
2666
- const raw = blockAttributes?.[SCRIDER_MARGIN_AFTER_KEY];
2667
- if (typeof raw === "string") {
2668
- const fromBlock = parseScriderMarginAfterEm(raw);
2669
- if (fromBlock !== void 0) return marginAfterStyleParts(fromBlock);
2679
+ const marginTop = resolveParagraphMarginEm(
2680
+ blockAttributes,
2681
+ SCRIDER_MARGIN_BEFORE_KEY,
2682
+ resolved?.paragraphSpacingBeforeEm
2683
+ );
2684
+ const marginBottom = resolveParagraphMarginEm(
2685
+ blockAttributes,
2686
+ SCRIDER_MARGIN_AFTER_KEY,
2687
+ resolved?.paragraphSpacingAfterEm
2688
+ );
2689
+ if (marginTop === void 0 && marginBottom === void 0) return [];
2690
+ const parts = [];
2691
+ if (marginTop !== void 0) {
2692
+ parts.push(`margin-top:${marginTop}em`);
2693
+ } else if (marginBottom !== void 0) {
2694
+ parts.push("margin-top:0");
2670
2695
  }
2671
- if (resolved?.paragraphSpacingAfterEm !== void 0) {
2672
- return marginAfterStyleParts(resolved.paragraphSpacingAfterEm);
2696
+ if (marginBottom !== void 0) {
2697
+ parts.push(`margin-bottom:${marginBottom}em`);
2673
2698
  }
2674
- return [];
2699
+ return parts;
2700
+ }
2701
+ function blockMarginAfterStyleParts(tag, blockAttributes, resolved) {
2702
+ if (!PARAGRAPH_SPACING_BLOCK_TAGS.has(tag)) return [];
2703
+ const marginBottom = resolveParagraphMarginEm(
2704
+ blockAttributes,
2705
+ SCRIDER_MARGIN_AFTER_KEY,
2706
+ resolved?.paragraphSpacingAfterEm
2707
+ );
2708
+ if (marginBottom === void 0) return [];
2709
+ return ["margin-top:0", `margin-bottom:${marginBottom}em`];
2710
+ }
2711
+ function blockMarginBeforeStyleParts(tag, blockAttributes, resolved) {
2712
+ if (!PARAGRAPH_SPACING_BLOCK_TAGS.has(tag)) return [];
2713
+ const marginTop = resolveParagraphMarginEm(
2714
+ blockAttributes,
2715
+ SCRIDER_MARGIN_BEFORE_KEY,
2716
+ resolved?.paragraphSpacingBeforeEm
2717
+ );
2718
+ if (marginTop === void 0) return [];
2719
+ return [`margin-top:${marginTop}em`];
2675
2720
  }
2676
2721
 
2677
2722
  // src/conversion/html/document-presentation.ts
@@ -2681,10 +2726,17 @@ function resolveDocumentPresentation(presentation) {
2681
2726
  const textIndentCm = typeof presentation.textIndentCm === "number" && presentation.textIndentCm > 0 ? presentation.textIndentCm : void 0;
2682
2727
  const listBlockIndentCm = typeof presentation.listBlockIndentCm === "number" && presentation.listBlockIndentCm > 0 ? presentation.listBlockIndentCm : void 0;
2683
2728
  const paragraphSpacingAfterEm = typeof presentation.paragraphSpacingAfterEm === "number" && Number.isFinite(presentation.paragraphSpacingAfterEm) && presentation.paragraphSpacingAfterEm >= 0 ? presentation.paragraphSpacingAfterEm : void 0;
2684
- if (lineSpacing === void 0 && paragraphSpacingAfterEm === void 0 && textIndentCm === void 0 && listBlockIndentCm === void 0) {
2729
+ const paragraphSpacingBeforeEm = typeof presentation.paragraphSpacingBeforeEm === "number" && Number.isFinite(presentation.paragraphSpacingBeforeEm) && presentation.paragraphSpacingBeforeEm >= 0 ? presentation.paragraphSpacingBeforeEm : void 0;
2730
+ if (lineSpacing === void 0 && paragraphSpacingAfterEm === void 0 && paragraphSpacingBeforeEm === void 0 && textIndentCm === void 0 && listBlockIndentCm === void 0) {
2685
2731
  return void 0;
2686
2732
  }
2687
- return { lineSpacing, paragraphSpacingAfterEm, textIndentCm, listBlockIndentCm };
2733
+ return {
2734
+ lineSpacing,
2735
+ paragraphSpacingAfterEm,
2736
+ paragraphSpacingBeforeEm,
2737
+ textIndentCm,
2738
+ listBlockIndentCm
2739
+ };
2688
2740
  }
2689
2741
  var TEXT_INDENT_TAGS = /* @__PURE__ */ new Set(["p"]);
2690
2742
  function documentPresentationListWrapperStyleParts(resolved) {
@@ -2702,7 +2754,7 @@ function documentPresentationStyleParts(tag, resolved) {
2702
2754
  function blockPresentationStyleParts(tag, blockAttributes, resolved) {
2703
2755
  return [
2704
2756
  ...blockLineHeightStyleParts(tag, blockAttributes, resolved),
2705
- ...blockMarginAfterStyleParts(tag, blockAttributes, resolved),
2757
+ ...blockParagraphMarginStyleParts(tag, blockAttributes, resolved),
2706
2758
  ...documentPresentationStyleParts(tag, resolved)
2707
2759
  ];
2708
2760
  }
@@ -2804,7 +2856,16 @@ function deltaToHtml(delta, options = {}) {
2804
2856
  counters = [];
2805
2857
  const codeLines = collectCodeBlockLines(lines, i);
2806
2858
  const language = getCodeBlockLanguage(line.attributes);
2807
- html += renderCodeBlock(codeLines, language, embedRenderers, pretty, blockHandlers, options);
2859
+ const codeBlockId = getCodeBlockId(line.attributes);
2860
+ html += renderCodeBlock(
2861
+ codeLines,
2862
+ language,
2863
+ embedRenderers,
2864
+ pretty,
2865
+ blockHandlers,
2866
+ options,
2867
+ codeBlockId
2868
+ );
2808
2869
  i += codeLines.length - 1;
2809
2870
  continue;
2810
2871
  }
@@ -3075,11 +3136,13 @@ function collectCodeBlockLines(lines, startIndex) {
3075
3136
  const startLine = lines[startIndex];
3076
3137
  if (!startLine) return codeLines;
3077
3138
  const startLang = getCodeBlockLanguage(startLine.attributes);
3139
+ const startId = getCodeBlockId(startLine.attributes);
3078
3140
  for (let i = startIndex; i < lines.length; i++) {
3079
3141
  const line = lines[i];
3080
3142
  if (!line || !line.attributes?.["code-block"]) break;
3081
3143
  const lang = getCodeBlockLanguage(line.attributes);
3082
- if (i > startIndex && lang !== startLang) break;
3144
+ const id = getCodeBlockId(line.attributes);
3145
+ if (i > startIndex && (lang !== startLang || id !== startId)) break;
3083
3146
  codeLines.push(line);
3084
3147
  }
3085
3148
  return codeLines;
@@ -3092,14 +3155,20 @@ function getCodeBlockLanguage(attributes) {
3092
3155
  }
3093
3156
  return void 0;
3094
3157
  }
3095
- function renderCodeBlock(codeLines, language, embedRenderers, pretty, blockHandlers, options) {
3158
+ function getCodeBlockId(attributes) {
3159
+ if (!attributes) return void 0;
3160
+ const id = attributes["code-block-id"];
3161
+ return typeof id === "string" ? id : void 0;
3162
+ }
3163
+ function renderCodeBlock(codeLines, language, embedRenderers, pretty, blockHandlers, options, codeBlockId) {
3096
3164
  const lineContents = codeLines.map(
3097
3165
  (line) => renderLineContent(line.ops, embedRenderers, blockHandlers, options)
3098
3166
  );
3099
3167
  const code = lineContents.join("\n");
3100
3168
  const langClass = language ? ` class="language-${escapeHtml(language)}"` : "";
3101
3169
  const langAttr = language ? ` data-language="${escapeHtml(language)}"` : "";
3102
- const html = `<pre${langAttr}><code${langClass}>${code}
3170
+ const idAttr = codeBlockId ? ` data-code-block-id="${escapeHtml(codeBlockId)}"` : "";
3171
+ const html = `<pre${langAttr}${idAttr}><code${langClass}>${code}
3103
3172
  </code></pre>`;
3104
3173
  return pretty ? html + "\n" : html;
3105
3174
  }
@@ -3313,6 +3382,7 @@ function htmlToDelta(html, options = {}) {
3313
3382
  let currentBlockAttributes = {};
3314
3383
  let pendingText = "";
3315
3384
  let atLineStart = true;
3385
+ let codeBlockIdSeq = 0;
3316
3386
  const context = {
3317
3387
  delta,
3318
3388
  get attributes() {
@@ -3525,6 +3595,8 @@ function htmlToDelta(html, options = {}) {
3525
3595
  }
3526
3596
  const codeBlockValue = language || true;
3527
3597
  currentBlockAttributes["code-block"] = codeBlockValue;
3598
+ const existingId = element.getAttribute("data-code-block-id");
3599
+ currentBlockAttributes["code-block-id"] = existingId || `cb-${++codeBlockIdSeq}`;
3528
3600
  const sourceElement = codeElement || element;
3529
3601
  const rawText = sourceElement.textContent ?? "";
3530
3602
  const text = rawText.endsWith("\n") ? rawText.slice(0, -1) : rawText;
@@ -4260,11 +4332,13 @@ function collectCodeBlock(lines, startIndex) {
4260
4332
  const startLine = lines[startIndex];
4261
4333
  if (!startLine) return codeLines;
4262
4334
  const startLang = getCodeBlockLanguage2(startLine.attributes);
4335
+ const startId = getCodeBlockId2(startLine.attributes);
4263
4336
  for (let i = startIndex; i < lines.length; i++) {
4264
4337
  const line = lines[i];
4265
4338
  if (!line || !line.attributes["code-block"]) break;
4266
4339
  const lang = getCodeBlockLanguage2(line.attributes);
4267
- if (i > startIndex && lang !== startLang) break;
4340
+ const id = getCodeBlockId2(line.attributes);
4341
+ if (i > startIndex && (lang !== startLang || id !== startId)) break;
4268
4342
  codeLines.push(line);
4269
4343
  }
4270
4344
  return codeLines;
@@ -4382,6 +4456,10 @@ function getCodeBlockLanguage2(attributes) {
4382
4456
  }
4383
4457
  return void 0;
4384
4458
  }
4459
+ function getCodeBlockId2(attributes) {
4460
+ const id = attributes["code-block-id"];
4461
+ return typeof id === "string" ? id : void 0;
4462
+ }
4385
4463
  function renderLineContent2(ops, embedRenderers, inCodeBlock, useLatexDelimiters = false, blockHandlers, prettyHtml = false, registry, softBreakStyle = "spaces", inTableCell = false) {
4386
4464
  let result = "";
4387
4465
  for (const op of ops) {
@@ -4735,6 +4813,7 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
4735
4813
  let pendingText = "";
4736
4814
  const spanAttrStack = [];
4737
4815
  const footnoteDefinitions = /* @__PURE__ */ new Map();
4816
+ let codeBlockIdSeq = 0;
4738
4817
  const context = {
4739
4818
  delta,
4740
4819
  pushText(text, attrs) {
@@ -5050,7 +5129,8 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
5050
5129
  }
5051
5130
  const lines = code.split("\n");
5052
5131
  const codeBlockAttr = {
5053
- "code-block": lang ?? true
5132
+ "code-block": lang ?? true,
5133
+ "code-block-id": `cb-${++codeBlockIdSeq}`
5054
5134
  };
5055
5135
  for (const line of lines) {
5056
5136
  context.pushText(line);
@@ -5064,7 +5144,10 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
5064
5144
  context.pushNewline();
5065
5145
  } else {
5066
5146
  const lines = value.split("\n");
5067
- const mathBlockAttr = { "code-block": "math" };
5147
+ const mathBlockAttr = {
5148
+ "code-block": "math",
5149
+ "code-block-id": `cb-${++codeBlockIdSeq}`
5150
+ };
5068
5151
  for (const line of lines) {
5069
5152
  context.pushText(line);
5070
5153
  context.pushNewline(mathBlockAttr);
@@ -5342,12 +5425,15 @@ function extractTableRegion(ops, hintOpIdx) {
5342
5425
  Registry,
5343
5426
  SCRIDER_LINE_HEIGHT_KEY,
5344
5427
  SCRIDER_MARGIN_AFTER_KEY,
5428
+ SCRIDER_MARGIN_BEFORE_KEY,
5345
5429
  alertBlockHandler,
5346
5430
  alignFormat,
5347
5431
  backgroundFormat,
5348
5432
  blockFormat,
5349
5433
  blockLineHeightStyleParts,
5350
5434
  blockMarginAfterStyleParts,
5435
+ blockMarginBeforeStyleParts,
5436
+ blockParagraphMarginStyleParts,
5351
5437
  blockPresentationStyleParts,
5352
5438
  blockquoteFormat,
5353
5439
  boldFormat,
@@ -5401,6 +5487,8 @@ function extractTableRegion(ops, hintOpIdx) {
5401
5487
  normalizeDelta,
5402
5488
  parseScriderLineHeightMultiplier,
5403
5489
  parseScriderMarginAfterEm,
5490
+ parseScriderMarginBeforeEm,
5491
+ parseScriderMarginEm,
5404
5492
  preloadRemark,
5405
5493
  resolveDocumentPresentation,
5406
5494
  resolveTablePresentation,